package com.dhcc.core.config;

import java.util.ArrayList;
import java.util.List;

import com.dhcc.core.config.properties.SsoProperties;
import com.dhcc.core.config.properties.SysProperties;
import com.dhcc.core.framework.constant.SsoClientTypeConst;
import com.dhcc.core.framework.security.client.cas.CasClient;
import com.dhcc.core.framework.security.client.cas.CasConfiguration;
import com.dhcc.core.framework.security.client.form.FormAuthenticator;
import com.dhcc.core.framework.security.client.hos.HosClient;
import com.dhcc.core.framework.security.client.oauth2.DthClient;
import com.dhcc.core.framework.security.client.wechat.WechatAuthenticator;
import com.dhcc.core.framework.security.filter.Pac4jCallbackUrlResolver;
import com.dhcc.core.framework.security.filter.Pac4jCasLogoutActionBuilder;
import com.dhcc.core.framework.security.filter.Pac4jOauth2LogoutActionBuilder;
import com.dhcc.core.framework.security.filter.Pac4jUrlResolver;
import com.dhcc.core.framework.util.CommonUtil;
import com.dhcc.core.modules.system.cache.config.ConfigCache;

import org.pac4j.cas.config.CasProtocol;
import org.pac4j.core.client.Client;
import org.pac4j.core.client.Clients;
import org.pac4j.core.config.Config;
import org.pac4j.http.client.indirect.FormClient;
import org.pac4j.oauth.client.WechatClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import io.buji.pac4j.context.ShiroSessionStore;

/**
 * Pac4jConfig
 * 
 * @author cyf
 * @version 2018-07-06 9:35
 **/
@Configuration
public class Pac4jConfig {

    @Autowired
    SysProperties sysProperties;

    @Autowired
    SsoProperties ssoProperties;

    /**
     * oauth2 client
     */
    private DthClient oauth2Client() {
        DthClient client = new DthClient(ssoProperties.getOauthKey(), ssoProperties.getOauthSecret());
        client.setName(SsoClientTypeConst.OAUTH2);
        client.setLogoutActionBuilder(new Pac4jOauth2LogoutActionBuilder<>());
        return client;
    }
    /**
     * hos client
     */
    private HosClient hosClient() {
    	HosClient client = new HosClient(ssoProperties.getOauthKey(), ssoProperties.getOauthSecret());
        client.setName(SsoClientTypeConst.HOS);
        client.setLogoutActionBuilder(new Pac4jOauth2LogoutActionBuilder<>());
        return client;
    }

    /**
     * cas client
     */
    private CasClient casClient() {
        final CasConfiguration casConfig = new CasConfiguration();
        // CAS server登录地址
        casConfig.setLoginUrl("/login");
        // CAS 版本，默认为 CAS30，我们使用的是 CAS20
        casConfig.setProtocol(CasProtocol.CAS20);
        casConfig.setAcceptAnyProxy(true);
        casConfig.setPrefixUrl("/");
        CasClient client = new CasClient(casConfig);
        client.setName(SsoClientTypeConst.CAS);
        client.setLogoutActionBuilder(new Pac4jCasLogoutActionBuilder<>());
        return client;
    }

    /**
     * form client
     */
    private FormClient formClient() {
        FormClient client = new FormClient("/login", new FormAuthenticator());
        client.setName(SsoClientTypeConst.FORM);
        return client;
    }

    /**
     * wechat client
     * @return
     */
    private WechatClient wechatClient(){
        String wxAppId = ConfigCache.me().getValueByKey("wx.appid","oa");
        String wxAppSecret = ConfigCache.me().getValueByKey("wx.appsecret");
        WechatClient client = new WechatClient(wxAppId,wxAppSecret);
        client.setName(SsoClientTypeConst.WECHAT);
        client.setAuthenticator(new WechatAuthenticator());
        return client;
    }
    /**
     * 登录client配置
     */
    @Bean
    @SuppressWarnings("rawtypes")
	public Clients pac4jClients(){
        List<Client> clients = new ArrayList<>();
        for (String type : ssoProperties.getTypes()) {
            if(CommonUtil.equals(type, SsoClientTypeConst.FORM)){
                clients.add(formClient());
            }
            if(CommonUtil.equals(type, SsoClientTypeConst.OAUTH2)){
                clients.add(oauth2Client());
            }
            if(CommonUtil.equals(type, SsoClientTypeConst.HOS)){
                clients.add(hosClient());
            }
            if(CommonUtil.equals(type, SsoClientTypeConst.CAS)){
                clients.add(casClient());
            }
            if(CommonUtil.equals(type, SsoClientTypeConst.WECHAT)){
                clients.add(wechatClient());
            }
        }
		Clients clts = new Clients("/callback",clients);
        clts.setUrlResolver(new Pac4jUrlResolver());
        clts.setCallbackUrlResolver(new Pac4jCallbackUrlResolver());
        return clts;
    }

    /**
     * pac4j配置
     * 
     * @param casClient
     * @param shiroSessionStore
     * @return
     */
    @Bean
    public Config config(Clients pac4jClients) {
        Config config = new Config(pac4jClients);
        config.setSessionStore(ShiroSessionStore.INSTANCE);
        return config;
    }

}